/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.source.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.thinkgem.jeesite.common.mapper.JaxbMapper;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.FileUtils;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.source.entity.EleSourceGroup;
import com.thinkgem.jeesite.modules.source.entity.EleSourceMultimedia;
import com.thinkgem.jeesite.modules.source.entity.alarm.EleSourceAlarm;
import com.thinkgem.jeesite.modules.source.entity.alarm.EleSourceAlarmGroup;
import com.thinkgem.jeesite.modules.source.entity.background.EleSourceBackground;
import com.thinkgem.jeesite.modules.source.entity.direction.EleSourceDirection;
import com.thinkgem.jeesite.modules.source.entity.direction.EleSourceDirectionGroup;
import com.thinkgem.jeesite.modules.source.entity.floor.EleSourceFloor;
import com.thinkgem.jeesite.modules.source.entity.floor.EleSourceFloored;
import com.thinkgem.jeesite.modules.source.entity.floor.Floor;
import com.thinkgem.jeesite.modules.source.entity.floor.FloorNode;
import com.thinkgem.jeesite.modules.source.entity.font.EleSourceFont;
import com.thinkgem.jeesite.modules.source.entity.image.EleSourceImage;
import com.thinkgem.jeesite.modules.source.entity.image.EleSourceImageGroup;
import com.thinkgem.jeesite.modules.source.entity.subtitle.EleSourceSubtitleGroup;
import com.thinkgem.jeesite.modules.source.entity.time.EleSourceDate;
import com.thinkgem.jeesite.modules.source.entity.time.EleSourceTime;
import com.thinkgem.jeesite.modules.source.entity.title.EleSourceTitle;
import com.thinkgem.jeesite.modules.source.entity.video.EleSourceVideo;
import com.thinkgem.jeesite.modules.source.entity.video.EleSourceVideoGroup;
import com.thinkgem.jeesite.modules.source.entity.weather.EleSourceWeather;
import com.thinkgem.jeesite.modules.source.entity.week.EleSourceWeek;
import com.thinkgem.jeesite.modules.source.service.alarm.EleSourceAlarmGroupService;
import com.thinkgem.jeesite.modules.source.service.background.EleSourceBackgroundService;
import com.thinkgem.jeesite.modules.source.service.direction.EleSourceDirectionGroupService;
import com.thinkgem.jeesite.modules.source.service.floor.EleSourceFloorService;
import com.thinkgem.jeesite.modules.source.service.floor.EleSourceFlooredService;
import com.thinkgem.jeesite.modules.source.service.floor.FloorNodeService;
import com.thinkgem.jeesite.modules.source.service.image.EleSourceImageGroupService;
import com.thinkgem.jeesite.modules.source.service.subtitle.EleSourceSubtitleGroupService;
import com.thinkgem.jeesite.modules.source.service.time.EleSourceDateService;
import com.thinkgem.jeesite.modules.source.service.time.EleSourceTimeService;
import com.thinkgem.jeesite.modules.source.service.title.EleSourceTitleService;
import com.thinkgem.jeesite.modules.source.service.video.EleSourceVideoGroupService;
import com.thinkgem.jeesite.modules.source.service.weather.EleSourceWeatherService;
import com.thinkgem.jeesite.modules.source.service.week.EleSourceWeekService;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.thinkgem.jeesite.modules.templet.entity.EleTemplet;
import com.thinkgem.jeesite.modules.templet.service.EleTempletService;
import com.thinkgem.jeesite.modules.source.dao.EleSourceGroupDao;
import com.thinkgem.jeesite.modules.source.entity.EleSource;
import com.thinkgem.jeesite.modules.publish.service.EleTempletPublishService;
import com.thinkgem.jeesite.modules.source.dao.EleSourceDao;

/**
 * 节目包管理Service
 * @author ZC
 * @version 2017-05-25
 */
@Service
@Transactional(readOnly = true)
public class EleSourceGroupService extends CrudService<EleSourceGroupDao, EleSourceGroup> {

	@Autowired
	private EleSourceDao eleSourceDao;
	@Autowired
	private EleSourceGroupDao eleSourceGroupDao;
	@Autowired
	private EleSourceSubtitleGroupService eleSourceSubtitleGroupService;
	@Autowired
	private EleSourceTitleService eleSourceTitleService;
	@Autowired
	private EleTempletService eleTempletService;
	@Autowired
	private FloorNodeService floorNodeService;
	@Autowired
	private EleSourceImageGroupService eleSourceImageGroupService;
	@Autowired
	private EleSourceVideoGroupService eleSourceVideoGroupService;
	@Autowired
	private EleSourceDirectionGroupService eleSourceDirectionGroupService;
	@Autowired
	private EleSourceBackgroundService eleSourceBackgroundService;
	@Autowired
	private EleSourceAlarmGroupService eleSourceAlarmGroupService;
	@Autowired	
	private EleSourceDateService eleSourceDateService;
	@Autowired
	private EleSourceTimeService eleSourceTimeService;
	
	@Autowired
	private EleSourceWeatherService eleSourceWeatherService;
	@Autowired
	private EleSourceWeekService eleSourceWeekService;
	@Autowired
	private EleSourceFloorService eleSourceFloorService;
	@Autowired
	private EleSourceFlooredService eleSourceFlooredService;
	@Autowired
	private EleSourceMultimediaService eleSourceMultimediaService;
	@Autowired
	private EleTempletPublishService eleTempletPublishService;
	
	public EleSourceGroup get(String id) {
		EleSourceGroup eleSourceGroup = super.get(id);
		eleSourceGroup.setEleSourceList(eleSourceDao.findList(new EleSource(eleSourceGroup)));
		return eleSourceGroup;
	}
	
	public List<EleSourceGroup> findList(EleSourceGroup eleSourceGroup) {
		return super.findList(eleSourceGroup);
	}
	public List<EleSource> findSourcesOnEquipment(String equipmentId,String status) {
		return eleSourceDao.findSourcesOnEquipment(equipmentId, status);
	}
	public Page<EleSourceGroup> findPage(Page<EleSourceGroup> page, EleSourceGroup eleSourceGroup) {
		return super.findPage(page, eleSourceGroup);
	}
	public Page<EleSourceGroup> findPageForCheck(Page<EleSourceGroup> page, List<User> users,String status) {
		page.setList(eleSourceGroupDao.findEleEleSourceGroupForCheck(users, status));
		return page;
	}
	@Transactional(readOnly = false)
	public int updateSource(EleSource entity){
		return eleSourceDao.update(entity);
	}
	@Transactional(readOnly = false)
	public int deleteSource(EleSource entity){
		return eleSourceDao.delete(entity);
	}
	public EleSource getSourceById(String id){
		return eleSourceDao.get(id);
	}
	@Transactional(readOnly = false)
	public void save(EleSourceGroup eleSourceGroup) {
		super.save(eleSourceGroup);
		for (EleSource eleSource : eleSourceGroup.getEleSourceList()){
			if (eleSource.getId() == null){
				continue;
			}
			if (EleSource.DEL_FLAG_NORMAL.equals(eleSource.getDelFlag())){
				if (StringUtils.isBlank(eleSource.getId())){
					eleSource.setGroup(eleSourceGroup);
					eleSource.preInsert();
					eleSourceDao.insert(eleSource);
				}else{
					eleSource.preUpdate();
					eleSourceDao.update(eleSource);
				}
			}else{
				eleSourceDao.delete(eleSource);
			}
		}
	}
	
	@Transactional(readOnly = false)
	public void delete(EleSourceGroup eleSourceGroup) {
		super.delete(eleSourceGroup);
		eleSourceDao.delete(new EleSource(eleSourceGroup));
	}
	@Transactional(readOnly = false)
	public int updateGroup(EleSourceGroup entity){
		return eleSourceGroupDao.update(entity);
	}
	@Transactional(readOnly = false)
	public int bathcUpdateGroupStatus(String groups,String status,String checker){
		return eleSourceGroupDao.batchUpdateGroupStatus(groups, status,checker);
	}
	public void createPackageForSourceGroup(EleSourceGroup eleSourceGroup,String basePath) throws IOException{
		List<EleSource> esList = eleSourceGroup.getEleSourceList();
		String egId = eleSourceGroup.getId();
		String encoding = "UTF-8";
	
		String filePath = basePath.replace("\\elevator\\","");
		Map<String,List<File>> fileMap = new HashMap<>();
		for(EleSource es:esList){
			String type = es.getType();
			if(type == null){
				continue;
			}
			List<File> files = new ArrayList<File>();
			String configName = type+".xml";
			File config = null;
			String configContent = "";
			switch(type){
//			case "image":
//				EleSourceImageGroup esig = eleSourceImageGroupService.get(es.getContent());
//				List<EleSourceImage> esiList = esig.getEleSourceImageList();
//				for(EleSourceImage esi:esiList){
//					files.add(new File(filePath+esi.getPath()));
//					String path = esi.getPath();
//					path = path.substring(path.lastIndexOf("/")+1, path.length());
//					esi.setPath(path);
//				}
//				configContent = JaxbMapper.toXml(esig, encoding);
//				config = new File(configName);
//				FileUtils.writeStringToFile(config, configContent,encoding, false);
//				files.add(config);
//				break;
//			case "video":
//				EleSourceVideoGroup esvg = eleSourceVideoGroupService.get(es.getContent());
//				List<EleSourceVideo> esvList = esvg.getEleSourceVideoList();
//				for(EleSourceVideo esv:esvList){
//					System.out.println(esv.getPath());
//					files.add(new File(filePath+esv.getPath()));
//					String path = esv.getPath();
//					path = path.substring(path.lastIndexOf("/")+1, path.length());
//					esv.setPath(path);
//				}
//				configContent = JaxbMapper.toXml(esvg, encoding);
//				config = new File(configName);
//				FileUtils.writeStringToFile(config, configContent,encoding, false);
//				files.add(config);
//				break;
			case "multimedia":
				EleSourceMultimedia eleSourceMultimedia = eleSourceMultimediaService.get(es.getContent());
				String videoId = eleSourceMultimedia.getVideoId();
				String imageId = eleSourceMultimedia.getImageId();
				if (!StringUtils.isEmpty(videoId)) {
					EleSourceVideoGroup esvg = eleSourceVideoGroupService.get(videoId);
					List<EleSourceVideo> esvList = esvg.getEleSourceVideoList();
					for (EleSourceVideo esv : esvList) {
						System.out.println(esv.getPath());
						files.add(new File(filePath + esv.getPath()));
						String path = esv.getPath();
						path = path.substring(path.lastIndexOf("/") + 1, path.length());
						esv.setPath(path);
					}
					eleSourceMultimedia.setVideoGroup(esvg);
				}
				if (!StringUtils.isEmpty(imageId)) {
					EleSourceImageGroup esig = eleSourceImageGroupService.get(imageId);
					List<EleSourceImage> esiList = esig.getEleSourceImageList();
					for (EleSourceImage esi : esiList) {
						files.add(new File(filePath + esi.getPath()));
						String path = esi.getPath();
						path = path.substring(path.lastIndexOf("/") + 1, path.length());
						esi.setPath(path);
					}
					eleSourceMultimedia.setImageGroup(esig);
				}
				configContent = JaxbMapper.toXml(eleSourceMultimedia, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "sub":
				EleSourceSubtitleGroup essg = eleSourceSubtitleGroupService.get(es.getContent());
				if(essg.getBgimage() != null){
					files.add(new File(filePath+essg.getBgimage()));
					String image = essg.getBgimage();
					image = image.substring(image.lastIndexOf("/")+1, image.length());
					essg.setBgimage(image);
				}
				essg.setBgcolor(essg.getBgcolor().replace("#", ""));
				essg.setFgcolor(essg.getFgcolor().replace("#", ""));
				configContent = JaxbMapper.toXml(essg, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "title":
				EleSourceTitle est = eleSourceTitleService.get(es.getContent());
				est.setBgcolor(est.getBgcolor().replace("#", ""));
				est.setFgcolor(est.getFgcolor().replace("#", ""));
				configContent = JaxbMapper.toXml(est, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "direction":
				EleSourceDirectionGroup esdg = eleSourceDirectionGroupService.get(es.getContent());
				if(esdg.getStop() != null){
					files.add(new File(filePath+esdg.getStop()));
					String stop = esdg.getStop();
					stop = stop.substring(stop.lastIndexOf("/")+1, stop.length());
					esdg.setStop(stop);
				}
				if(esdg.getUptips() != null){
					files.add(new File(filePath+esdg.getUptips()));
					String uptips = esdg.getUptips();
					uptips = uptips.substring(uptips.lastIndexOf("/")+1, uptips.length());
					esdg.setUptips(uptips);
				}
				if(esdg.getUpstop() != null){
					files.add(new File(filePath+esdg.getUpstop()));
					String upstop = esdg.getUpstop();
					upstop = upstop.substring(upstop.lastIndexOf("/")+1, upstop.length());
					esdg.setUpstop(upstop);
				}
				if(esdg.getDeftips()!= null){
					files.add(new File(filePath+esdg.getDeftips()));
					String deftips = esdg.getDeftips();
					deftips = deftips.substring(deftips.lastIndexOf("/")+1, deftips.length());
					esdg.setDeftips(deftips);
				}
				if(esdg.getDownstop() != null){
					files.add(new File(filePath+esdg.getDownstop()));
					String downstop = esdg.getDownstop();
					downstop = downstop.substring(downstop.lastIndexOf("/")+1, downstop.length());
					esdg.setDownstop(downstop);
				}
				if(esdg.getDowntips() != null){
					files.add(new File(filePath+esdg.getDowntips()));
					String downtips = esdg.getDowntips();
					downtips = downtips.substring(downtips.lastIndexOf("/")+1, downtips.length());
					esdg.setDowntips(downtips);
				}
				for(EleSourceDirection ed:esdg.getEleSourceDirectionList()){
					String node = ed.getNode();
					node = node.substring(node.lastIndexOf("/")+1, node.length());
					ed.setNode(node);
				}
				esdg.devide();
				configContent = JaxbMapper.toXml(esdg, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "background":
				EleSourceBackground esbg = eleSourceBackgroundService.get(es.getContent());
				if(esbg.getBgGif() != null){
					files.add(new File(filePath+esbg.getBgGif()));
					String gif = esbg.getBgGif();
					gif = gif.substring(gif.lastIndexOf("/")+1, gif.length());
					esbg.setBgGif(gif);
				}
				if(esbg.getBgImage() != null){
					files.add(new File(filePath+esbg.getBgImage()));
					String image = esbg.getBgImage();
					image = image.substring(image.lastIndexOf("/")+1, image.length());
					esbg.setBgImage(image);
				}
				esbg.setColor(esbg.getColor().replace("#",""));
				configContent = JaxbMapper.toXml(esbg, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "alarm":
				EleSourceAlarmGroup esag = eleSourceAlarmGroupService.get(es.getContent());
				List<EleSourceAlarm> eaList = esag.getEleSourceAlarmList();
				if(esag.getDefaudio() != null){
					files.add(new File(filePath+esag.getDefaudio()));
					
					String def = esag.getDefaudio();
					def = def.substring(def.lastIndexOf("/")+1, def.length());
					esag.setDefaudio(def);
				}
				for(EleSourceAlarm ea:eaList){
					files.add(new File(filePath+ea.getVolume()));
					files.add(new File(filePath+ea.getImage()));
					
					String volume = ea.getVolume();
					volume = volume.substring(volume.lastIndexOf("/")+1, volume.length());
					ea.setVolume(volume);
					
					String image = ea.getImage();
					image = image.substring(image.lastIndexOf("/")+1, image.length());
					ea.setImage(image);
				}
				configContent = JaxbMapper.toXml(esag, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "date":
				EleSourceDate esd = eleSourceDateService.get(es.getContent());
				esd.setColor(esd.getColor().replace("#",""));

				configContent = JaxbMapper.toXml(esd, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "time":
				EleSourceTime estime = eleSourceTimeService.get(es.getContent());
				estime.setColor(estime.getColor().replace("#",""));

				configContent = JaxbMapper.toXml(estime, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "weather":
				EleSourceWeather esw = eleSourceWeatherService.get(es.getContent());
				esw.setColor(esw.getColor().replace("#",""));

				configContent = JaxbMapper.toXml(esw, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "week":
				EleSourceWeek esweek = eleSourceWeekService.get(es.getContent());
				esweek.setColor(esweek.getColor().replace("#",""));

				configContent = JaxbMapper.toXml(esweek, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "floor":
				EleSourceFloor esfloor = eleSourceFloorService.get(es.getContent());
				esfloor.setFloornodes(floorNodeService.getByGroupId(esfloor.getId()));
				if(esfloor.getVolumeSelect() != null){
					String volume = esfloor.getVolumeSelect();
					files.add(new File(filePath+esfloor.getVolumeSelect()));
					volume = volume.substring(volume.lastIndexOf("/")+1, volume.length());
					esfloor.setVolumeSelect(volume);
				}
				for(FloorNode f:esfloor.getFloornodes()){
					if(f.getFloorimg() != null){
						String image = f.getFloorimg();
						files.add(new File(filePath+f.getFloorimg()));
						image = image.substring(image.lastIndexOf("/")+1, image.length());
						f.setFloorimg(image);
					}
				}
				for(Floor f:esfloor.getFloors()){
					if(f.getVolumeCn() != null){
						String volume = f.getVolumeCn();
						files.add(new File(filePath+f.getVolumeCn()));
						volume = volume.substring(volume.lastIndexOf("/")+1, volume.length());
						f.setVolumeCn(volume);;
					}
					if(f.getVolumeEn() != null){
						String volume = f.getVolumeEn();
						files.add(new File(filePath+f.getVolumeEn()));
						volume = volume.substring(volume.lastIndexOf("/")+1, volume.length());
						f.setVolumeEn(volume);
					}
				}
				configContent = JaxbMapper.toXml(esfloor, encoding).replaceAll("<floorimg>","").replaceAll("</floorimg>","");
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			case "floored":
				EleSourceFloored esfloored = eleSourceFlooredService.get(es.getContent());
				configContent = JaxbMapper.toXml(esfloored, encoding);
				config = new File(configName);
				FileUtils.writeStringToFile(config, configContent,encoding, false);
				files.add(config);
				break;
			default:
				break;
			}
			fileMap.put(type, files);
			System.out.println(configContent);
		}
		
		String zipPath = basePath + "/theme/source/"+egId+"/";
		String zipName = egId + ".zip";	
		if(eleSourceGroup.getTemplet() != null && !StringUtils.isEmpty(eleSourceGroup.getTemplet().getId())){
			String templateId = eleSourceGroup.getTemplet().getId();
			
			EleTemplet eleTemplet = eleTempletService.get(templateId);


			EleSourceFont est = eleTemplet.getFont();

			String fontFile = filePath + est.getFont();
			String fontName = est.getFont();
			if(fontName != null){
				fontName = fontName.substring(fontName.lastIndexOf("/") + 1, fontName.length());
	            eleTemplet.setFont(new EleSourceFont("", "font/"+fontName));
			}

			File font = new File(fontFile);
			List<File> fonts = new ArrayList<File>();
			fonts.add(font);
			fileMap.put("font", fonts);
			
			String destPath = basePath + "/theme/conf/"+templateId+"/theme.xml";
			String eleTempletXML = eleTempletPublishService.eleTempletToXml(eleTemplet);
			File theme = new File(destPath);
			FileUtils.writeStringToFile(theme, eleTempletXML,encoding, false);
			List<File> themes = new ArrayList<>();
			themes.add(theme);
			fileMap.put("theme", themes);
			
		}
		zipFiles(zipPath,zipName,fileMap);

	}
	public boolean zipFiles(String zipPath, String zipName, Map<String,List<File>> map) {

		// String tmpFileName = "report.zip";
		byte[] buffer = new byte[1024];
		// String strZipPath =
		// COM_REPORT_PATH+"/"+user.getOid()+"/"+report.getOid()+"/"+tmpFileName;

		String strZipPath = zipPath + "/" + zipName;
		try {
			File tmpZip = new File(zipPath);
			if (!tmpZip.exists())
				tmpZip.mkdirs();
			File tmpZipFile = new File(strZipPath);
			if (!tmpZipFile.exists())
				tmpZipFile.createNewFile();

			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(strZipPath));
			Set<String> keys = map.keySet();
			for(String key:keys){
				List<File> files = map.get(key);
				String dir = key+"/";
				if(key.equals("theme")){
					dir = "/";
				}
				//增加外部文件夹
				out.putNextEntry(new ZipEntry(dir));  
				System.out.println(key);
				System.out.println(files.size());
				for (int i = 0; i < files.size(); i++) {
					File f = files.get(i);
					if(f.isDirectory()){
						continue;
					}
					FileInputStream fis = new FileInputStream(f);
					out.putNextEntry(new ZipEntry(dir+files.get(i).getName()));
					// 设置压缩文件内的字符编码，不然会变成乱码
					out.setEncoding("UTF-8");
					int len;
					// 读入需要下载的文件的内容，打包到zip文件
					while ((len = fis.read(buffer)) > 0) {
						out.write(buffer, 0, len);
					}
					out.closeEntry();
					fis.close();
				}
				out.closeEntry();
			}
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}
}